﻿using AutoMapper.Features;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wq.Extensions.Common;
using Wq.Extensions.Repository;
using Wq.MeetingService.Entities;
using Wq.MeetingService.Models;
using Wq.Model;
using XAct;

namespace Wq.MeetingService
{
    /// <summary>
    /// 场地 
    /// </summary>
    public class VenueService : SqlSugarBaseRepository<VenueInfo>, IAddSingleton
    {
        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="pageModel"></param>
        /// <returns></returns>
        public List<VenueView> List(PageModel<VenueQuery> pageModel)
        {
            pageModel.OrderbyName ="p."+ pageModel.OrderbyName;
            int count = 0;
            var list = Context.Queryable<VenueInfo,CategoryInfo>((p,c) => new JoinQueryInfos(JoinType.Left, p.CategoryId == c.Id))
                .WhereIF(!SqlFunc.IsNullOrEmpty(pageModel.Entity.Name), p => p.Name.Contains(pageModel.Entity.Name))
                .WhereIF(pageModel.Entity.CategoryId.HasValue, p => p.CategoryId == pageModel.Entity.CategoryId)
                .WhereIF(pageModel.Entity.RegionId.HasValue, p => p.RegionFullIds.Contains($"{pageModel.Entity.RegionId},"))
                .WhereIF(pageModel.Entity.MinArea.HasValue && pageModel.Entity.MinArea > 0, p => p.MinArea >= pageModel.Entity.MinArea)
                .WhereIF(pageModel.Entity.MaxArea.HasValue && pageModel.Entity.MaxArea > 0, p => p.MaxArea <= pageModel.Entity.MaxArea)
                .WhereIF(pageModel.Entity.MinPeople.HasValue && pageModel.Entity.MinPeople > 0, p => p.MinPeople >= pageModel.Entity.MinPeople)
                .WhereIF(pageModel.Entity.MaxPeople.HasValue && pageModel.Entity.MaxPeople > 0, p => p.MaxPeople <= pageModel.Entity.MaxPeople)
                .WhereIF(pageModel.Entity.MinMeetingRoomPrice.HasValue && pageModel.Entity.MinMeetingRoomPrice > 0, p => p.MinMeetingRoomPrice >= pageModel.Entity.MinMeetingRoomPrice)
                .WhereIF(pageModel.Entity.MaxMeetingRoomPrice.HasValue && pageModel.Entity.MaxMeetingRoomPrice > 0, p => p.MaxMeetingRoomPrice <= pageModel.Entity.MaxMeetingRoomPrice)
                .WhereIF(pageModel.BeginDateTime.HasValue, p => p.OpeningDate >= pageModel.BeginDateTime)
                .WhereIF(pageModel.EndDateTime.HasValue, p => p.OpeningDate <= pageModel.EndDateTime)
                .OrderBy(pageModel.GetOrderbyString())
                .Select((p, c) => new VenueView
                {
                    Id = p.Id,
                    Name = p.Name,
                    CategoryName = c.Name,
                    RegionName = p.RegionFullName,
                    Address = p.Address,
                    Visits = p.Visits,
                    MinArea = p.MinArea,
                    MaxArea = p.MaxArea,
                    MinPeople = p.MinPeople,
                    MaxPeople = p.MaxPeople,
                    MinMeetingRoomPrice = p.MinMeetingRoomPrice,
                    MaxMeetingRoomPrice = p.MaxMeetingRoomPrice,
                    MeetingRoomCount = p.MeetingRoomCount,
                    GuestRoomCount = p.GuestRoomCount,
                    ParkingCount = p.ParkingCount,
                    OpeningDate = p.OpeningDate,
                    CreateTime = p.CreateTime,
                    Sequence = p.Sequence
                },true)
            .Mapper(p => {
            })
            .ToPageList(pageModel.Page.Index, pageModel.Page.Size, ref count);
            pageModel.Page.Num= count;
            return list;

        }

        /// <summary>
        /// 获取前top个场地
        /// </summary>
        /// <param name="cityRegionId"></param>
        /// <returns></returns>
        public List<VenueBaseView> ListByCity(long regionId,long businessId,int top)
        {
           var list = Context.Queryable<VenueInfo, CategoryInfo>((v, c) => new JoinQueryInfos(JoinType.Left, v.CategoryId == c.Id))
           .Where((v, c) => v.RegionFullIds.Contains(regionId + ",") )
           .WhereIF(businessId > 0,(v,c) => v.BusinessId == businessId)
           .OrderByDescending((v, c) => v.Sequence)
           .Select((v, c) => new VenueBaseView
           {
               Id = v.Id,
               Name = v.Name,
               CategoryName = c.Name,
           }, true)
           .Mapper(c => {

           })
           .Take(top)
           .ToList();
            var ids = list.Select(p => p.Id);
            var thumbnails = Context.Queryable<MeetingThumbnailInfo>().Where(p => ids.Contains(p.VenueId) && p.TypeId == Models.Enum.PositionType.Exterior).ToList();
            list.ForEach(item => item.Thumbnail = thumbnails.Where(p => p.VenueId == item.Id).FirstOrDefault()?.FilePath);
            return list;
        }


        /// <summary>
        /// 修改排序
        /// </summary>
        /// <param name="id"></param>
        /// <param name="sequence"></param>
        public void UpdateSequence(long id, long sequence) => Context.Updateable<VenueInfo>().SetColumns(p => p.Sequence == sequence).Where(p => p.Id == id).ExecuteCommand();

        /// <summary>
        /// 编辑内容转实体
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        private VenueInfo EditToModel(VenueEdit info)
        {
            var model = info.Map<VenueInfo>();
            if (info.Images.Count > 0)
            {
                List<MeetingThumbnailInfo> thumbnails = new List<MeetingThumbnailInfo>();
                foreach (var item in info.Images)
                    thumbnails.AddRange(item.Value.Select(p => new MeetingThumbnailInfo { SourceRoomId = 0, FilePath = p, VenueId = 0, TypeId = item.Key }).ToList());
                model.Thumbnails = thumbnails;
            }

            if (info.Configs.Count > 0)
            {
                List<VenueFacilitieInfo> VenueFacilities = new List<VenueFacilitieInfo>();
                foreach (var item in info.Configs)
                    VenueFacilities.AddRange(item.Value.Select(p => new VenueFacilitieInfo { MeetingRoomId = 0, FacilitieId = p, VenueId = info.Id, TypeId = item.Key }).ToList());
                model.Facilities = VenueFacilities;
            }
            if (info.VenueFeatures.Count > 0)
                model.Features = info.VenueFeatures.Select(p => new VenuFeaturesInfo { Id = 0, FeaturesId = p, VenueId = info.Id, MeetingRoomId = 0, TypeId = Models.Enum.PositionType.Site }).ToList();

            return model;
        }
        /// <summary>
        /// 插入
        /// </summary>
        /// <param name="manager"></param>
        public void Create(VenueEdit info)
        {
            var model = EditToModel(info);
            model.CreateTime = DateTime.Now;
            Context.InsertNav(model)
                .Include(p => p.Facilities)
                .Include(p => p.Thumbnails)
                .Include(p => p.Features).ExecuteCommand();

        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="manager"></param>
        public void Save(VenueEdit info)
        {
            Context.Ado.UseTran(() => {
                var model = EditToModel(info);
                //Context.Updateable(model).IgnoreColumns(it => new { it.CreateTime, it.Visits,it.MinArea,it.MaxArea,it.MinPeople,it.MaxPeople,it.MeetingRoomCount,it.MinMeetingRoomPrice,it.MaxMeetingRoomPrice,it.GuestRoomCount,it.MinGuestRoomPrice,it.MaxGuestRoomPrice }).ExecuteCommand();
                Context.Updateable(model).UpdateColumns(it => new { it.Name, it.CategoryId, it.RegionId,it.CityRegionId, it.RegionFullIds, it.RegionFullName, it.Address, it.Description, it.Longitude, it.Latitude, it.ParkingCount, it.BusinessId,it.Tag }).ExecuteCommand();
                Context.Deleteable<MeetingThumbnailInfo>(p => p.VenueId == info.Id && p.SourceRoomId == 0).ExecuteCommand();
                Context.Deleteable<VenueFacilitieInfo>(p => p.VenueId == info.Id && p.MeetingRoomId == 0).ExecuteCommand();
                Context.Deleteable<VenuFeaturesInfo>(p => p.VenueId == info.Id && p.MeetingRoomId == 0).ExecuteCommand();

                model.Thumbnails.ForEach(item => item.VenueId = info.Id);
                model.Facilities.ForEach(item => item.VenueId = info.Id);
                model.Features.ForEach(item => item.VenueId = info.Id);



                Context.Insertable(model.Thumbnails).ExecuteCommand();
                Context.Insertable(model.Facilities).ExecuteCommand();
                Context.Insertable(model.Features).ExecuteCommand();
               
            });
        }

        
    }
}
